package com.record.utils;



import org.apache.commons.math3.distribution.NormalDistribution;
import java.util.Arrays;

public class MannWhitneyUCalculator {

    /**
     * Mann–Whitney U 检验（非参数检验，适用于两独立样本）
     */
    public static MannWhitneyResult test(double[] x, double[] y) {
        int n1 = x.length, n2 = y.length;
        double[] combined = new double[n1 + n2];
        System.arraycopy(x, 0, combined, 0, n1);
        System.arraycopy(y, 0, combined, n1, n2);

        // 排序并计算秩
        double[] sorted = Arrays.copyOf(combined, combined.length);
        Arrays.sort(sorted);

        // 分配秩次
        double[] ranks = new double[combined.length];
        for (int i = 0; i < combined.length; i++) {
            for (int j = 0; j < sorted.length; j++) {
                if (combined[i] == sorted[j]) {
                    ranks[i] = j + 1;
                    break;
                }
            }
        }

        // 计算第一组秩和
        double rankSum1 = 0.0;
        for (int i = 0; i < n1; i++) rankSum1 += ranks[i];

        // 计算U值
        double U1 = rankSum1 - n1 * (n1 + 1) / 2.0;
        double U2 = n1 * n2 - U1;
        double U = Math.min(U1, U2);

        // 计算Z值和P值
        double mu = n1 * n2 / 2.0;
        double sigma = Math.sqrt(n1 * n2 * (n1 + n2 + 1) / 12.0);
        double z = (U - mu) / sigma;

        NormalDistribution nd = new NormalDistribution();
        double pValue = 2 * (1 - nd.cumulativeProbability(Math.abs(z)));

        return new MannWhitneyResult(U, z, pValue);
    }
}

